package com.aizuda.redislock;

import com.aizuda.redislock.annotation.DistributedLimit;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @author zhongjiahua
 * @date 2021-11-28
 * @Description: 测试分布式锁方式
 */
@RestController
@RequiredArgsConstructor
public class LockTestController {
    private final LockTestComponent lockTestComponent;

    /**
     * 测试分布式锁的接口，建议多开几个实例测试、
     * 支持可重复
     *
     * @param name 参数
     * @return map
     */
    @GetMapping("/lock-test")
    @DistributedLimit(
            // 唯一标示，支持SpEL表达式（可无），'#name!=null?#name:'default'' 为获取当前访问参数 name 内容，如果为空，则默认为 'default'
            key = "#name!=null?#name:'default'",
            // 指定时间获取锁，如果在指定时间获取不到，则抛出对应异常，捕获此异常即可
            expire = "5s",
            // 提示消息
            message = "您操作的太快了"
    )
    public Map<String, Object> testLock(String name) {
        try {
            TimeUnit.SECONDS.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
            Thread.currentThread().interrupt();
        }
        lockTestComponent.testLock(name);

        return new HashMap<String, Object>(4) {{
            put("name", Optional.ofNullable(name).orElse("default string"));
        }};
    }

    /**
     * 测试自定义key策略
     *
     * @param name 参数
     * @return map
     */
    @GetMapping("/custom-key-lock-test")
    @DistributedLimit(
            // 唯一标示，支持SpEL表达式（可无），'#name!=null?#name:'default'' 为获取当前访问参数 name 内容，如果为空，则默认为 'default'
            key = "#name!=null?#name:'default'",
            // 指定时间获取锁，如果在指定时间获取不到，则抛出对应异常，捕获此异常即可
            expire = "5s",
            // 提示消息
            message = "您操作的太快了"
    )
    public Map<String, Object> customKeyLock(String name) {
        try {
            TimeUnit.SECONDS.sleep(20);
        } catch (InterruptedException e) {
            e.printStackTrace();
            Thread.currentThread().interrupt();
        }
        lockTestComponent.testLock(name);

        return new HashMap<String, Object>(4) {{
            put("name", Optional.ofNullable(name).orElse("default string"));
        }};
    }
}
